#include <typeinfo>
#include <vector>
#include <cstdint>
#include <cassert>
#include <string>
#include <cstring>
#include <iostream>
#include "Log.hpp"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <functional>
#include <sys/epoll.h>
#include <unordered_map>
#include <mutex>
#include <thread>
#include <sys/eventfd.h>
#include <memory>
#include <sys/timerfd.h>
#include <condition_variable>


const uint64_t Buffer_Default_Size = 1024;

#include <ctime>

/**********************************************************
 * 设置了三个等级的信息,小于默认等级的信息打印不出来
 * 打印时间 那个文件 哪一行
 *********************************************************/
#define INF 0
#define DBG 1
#define ERR 2
#define LOG_DEFAULT_LEVEL DBG
#define LOG(level,format,...) do{\
        if(level < LOG_DEFAULT_LEVEL) break;\
        time_t t = time(NULL);\
        struct tm *ltm = localtime(&t);\
        char tmp[32] = {0};\
        strftime(tmp,31,"%Y-%m-%d %H:%M:%S",ltm);\
        fprintf(stdout,"[%p %s %s:%d] " format "\n",(void*)pthread_self(),tmp,__FILE__,__LINE__,##__VA_ARGS__);\
}while(0)

#define INF_LOG(format,...) LOG(INF,format,##__VA_ARGS__)
#define DBG_LOG(format,...) LOG(DBG,format,##__VA_ARGS__)
#define ERR_LOG(format,...) LOG(ERR,format,##__VA_ARGS__)



class Buffer
{
    private:
        std::vector<char> _buffer;//使用vector进行内存空间管理
        uint64_t _reader_idx;//读偏移
        uint64_t _writer_idx;//写偏移
    public:
        Buffer():_reader_idx(0),_writer_idx(0),_buffer(Buffer_Default_Size){}
        //获取_buffer的内存空间起始地址
        char *Begin(){ return &(*_buffer.begin()); }
        //获取当前写入位置起始地址
        char *WritePosition(){
            //_buffer的内存空间起始地址,加上写偏移量
            return Begin() + _writer_idx;
        }
        //获取当前读取位置起始地址
        char *ReadPosition(){
            //_buffer的内存空间起始地址,加上读偏移量
            return Begin() + _reader_idx;
        }
        //获取缓冲区末尾空闲空间大小--写偏移位置之后的空闲空间,总体空间大小减去写偏移
        uint64_t TailIdleSize(){
            return _buffer.size() - _writer_idx;
        }
        //获取缓冲区起始空闲空间大小--读偏移位置之前的空闲空间
        uint64_t headTdleSize(){
            return _reader_idx;
        }
        //获取可读数据大小
        uint64_t ReadAbleSize(){
            return _writer_idx - _reader_idx;
        }
        //将读偏移向后移动
        void MoveReadOffset(uint64_t len){
            if(len == 0) return;
            assert(len <= ReadAbleSize());
            _reader_idx += len;
        }
        //将写偏移向后移动
        void MoveWriteOffset(uint64_t len){
            //向后移动的大小,必须小于当前后边的空闲空间大小
            //在使用这个函数之前会确保可写空间足够
            assert(len <= TailIdleSize());
            _writer_idx += len;
        }
        //确保可写空间足够(整体空闲空间足够就移动数据,否则就扩容)
        void EnsureWriteSpace(uint64_t len){
            //如果末尾空闲空间大小足够,直接返回
            if(len <= TailIdleSize()) { return; }
            //末尾空闲空间不够,则判断加上起始位置的空闲空间大小是否足够,足够就将可读数据移动到起始位置
            if(TailIdleSize() + headTdleSize() >= len){
                //将可读数据移动到起始位置
                //先保存可读数据的大小,后边作为新的写偏移量
                uint64_t size = ReadAbleSize();
                //拷贝数据,(被拷贝的数据起始位置,被拷贝的数据最终位置,拷贝的数据放在哪里的起始位置)
                std::copy(ReadPosition(),WritePosition(),Begin());
                _reader_idx = 0;    //可读数据放到起始位置之后,将读偏移置为0
                _writer_idx = size; //可读数据放到起始位置之后,写偏移要重置为可读数据长度,之后从这里开始写
            }
            else{
                //总体空间不够,需要扩容,不移动数据,直接在写偏移后边扩容足够空间即可
                _buffer.resize(_writer_idx + len);
            }
        }
        //写入数据
        void Write (const void *data,uint64_t len){
            //1.保证有足够空间
            EnsureWriteSpace(len);
            //2.拷贝数据
            const char *start = (const char*)data;
            std::copy(start,start + len,WritePosition());
        }
        void WriteAndPush(const void *data,uint64_t len){
            Write(data,len);
            MoveWriteOffset(len);
        }
        void WriteString(const std::string &data){
            Write((void*)data.c_str(),data.size());
        }
        void WriteStringAndPush(const std::string &data){
            WriteString(data);
            MoveWriteOffset(data.size());
        }
        void WriteBuffer(Buffer &data){
            Write(data.ReadPosition(),data.ReadAbleSize());
        }
        void WriteBufferAndPush(Buffer &data){
            WriteBuffer(data);
            MoveWriteOffset((data.ReadAbleSize()));
        }
        //读取数据
        void Read(void *buf,uint64_t len){
            //严格要求要获取的数据大小必须小于可读数据大小
            assert(len <= ReadAbleSize());
            std::copy(ReadPosition(),ReadPosition() + len,(char*)buf);
        }
        void ReadAndPop(void *buf,uint64_t len){
            Read(buf,len);
            MoveReadOffset(len);
        }
        //读取多大的长度当做字符串
        std::string ReadAsString(uint64_t len){
            //严格要求要获取的数据大小必须小于可读数据大小
            assert(len <= ReadAbleSize());
            std::string str;
            str.resize(len);
            Read(&str[0],len);//这里不能用str.c_str()是因为它返回的是 const char* 类型,指针指向的内存数据不能修改
            return str;
        }
        std::string ReadAsStringAndPop(uint64_t len){
            //严格要求要获取的数据大小必须小于可读数据大小
            assert(len <= ReadAbleSize());
            std::string ret = ReadAsString(len);
            MoveReadOffset(len);
            return ret;
        }
        /**************************************** 
         * 寻找换行字符
         * 找到返回'\n'的地址,没找到返回NULL
        *****************************************/
        char *FindCRCF(){   
            char *res = (char*)memchr(ReadPosition(),'\n',ReadAbleSize());
            return res;
        }
        std::string GetLine(){
            char *pos = FindCRCF();
            if(pos == NULL)
                return "";
            //+1是为了把换行字符取出来
            return ReadAsString(pos - ReadPosition() + 1);
        }
        std::string GetLineAndPop(){
            std::string str = GetLine();
            MoveReadOffset(str.size());
            return str;
        }
        //清空缓冲区
        void clear(){
            _reader_idx = 0;
            _writer_idx = 0;
        }
};


#define MAX_LISTEN 1024
class Socket
{
    private:
        int _sockfd;
    public:
    Socket():_sockfd(-1){}
    Socket(int fd):_sockfd(fd){}
    ~Socket(){ Close(); }

    int Fd(){ return _sockfd; }
    //创建套接字
    bool Create(){
        // int socket(int domain, int type, int protocol);
        _sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if (_sockfd < 0) {
                ERR_LOG("CREATE SOCKET FAILED!!");
                return false;
            }
            return true;
    }
    //绑定地址信息
    bool Bind(const std::string &ip,const uint16_t &port){
        //1.组织ipv4地址结构
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = inet_addr(ip.c_str());   //INADDR_ANY;   //inet_addr(ip.c_str());
        socklen_t len = sizeof(struct sockaddr_in);
        //2.使用bind函数进行绑定
        //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
        int ret = bind(_sockfd,(struct sockaddr*)&addr,len);
        if(ret < 0){
            ERR_LOG("bind address failed");
            return false;
        }
        return true;
    }
    //开始监听
    bool Listen(int backlog = MAX_LISTEN){
        //int listen(int sockfd, int backlog);
        int ret = listen(_sockfd,backlog);
        if(ret < 0){
            ERR_LOG("socket listen failed");
            return false;
        }
        return true;
    }
    //向服务器发起连接
    bool Connect(const std::string &ip,const uint16_t &port){
        //1.组织ipv4地址结构
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = inet_addr(ip.c_str());
        socklen_t len = sizeof(struct sockaddr_in);
        //2.使用connect函数进行发起连接
         //int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
        int ret = connect(_sockfd,(struct sockaddr*)&addr,len);
        if(ret < 0){
            ERR_LOG("connect server failed");
            return false;
        }
        return true;
    }
    //获取新连接
    int Accept(){
        //int accept(int sockfd, struct sockaddr *_Nullable restrict addr,socklen_t *_Nullable restrict addrlen);
        int newfd = accept(_sockfd,NULL,NULL);
        if(newfd < 0){
            ERR_LOG("socket accept failed");
            return -1;
        }
        return newfd;
    }
    //接受数据
    ssize_t Recv(void *buf,size_t len,int flag = 0){
        // ssize_t recv(int sockfd, void buf[.len], size_t len,int flags);
        //自己理解: ssize_t recv(int sockfd, void *buf, size_t len,int flag);
        //返回值有三种:
        // < 0  表示出错了
        // = 0  表示连接断开了
        // > 0  表示接受到数据了
        ssize_t ret = recv(_sockfd,buf,len,flag);
        if(ret <= 0){
            //EAGAIN  当前socket的接收缓冲区中没有数据了,在非阻塞的情况下才会有这个错误
            //EINTR   表示当前的socket是阻塞等待,被信号打断了
            if(errno == EAGAIN || errno == EINTR)
                return 0;//表示这次接收没有接收到数据
            ERR_LOG("socket recv failed");
            return -1;
        }
        return ret;//实际接受数据的长度
    }
    ssize_t NonBlockRecv(void *buf,size_t len){
        return Recv(buf,len,MSG_DONTROUTE);//MSG_DONTROUTE 表示当前接受为非阻塞,没有数据就报错返回
    }
    //发送数据
    ssize_t Send(const void *buf,size_t len,int flag = 0){
        // ssize_t send(int sockfd, const void buf[.len], size_t len, int flags);
        //自己理解: ssize_t send(int sockfd,void *data, size_t len, int flags);
        ssize_t ret = send(_sockfd,buf,len,flag);
        if(ret < 0){
            if(errno == EAGAIN || errno == EINTR){
                return 0;
            }
            ERR_LOG("socket send failed");
            return -1;
        }
        return ret;//实际发送的数据长度
    }
    ssize_t NonBlockSend(void *buf,size_t len){
        if(len == 0) return 0;
        return Send(buf,len,MSG_DONTROUTE);//MSG_DONTROUTE 表示当前发送为非阻塞,没有数据就报错返回
    }
    //关闭套接字
    void Close(){
        // int close(int fd);
        if(_sockfd != -1){
             close(_sockfd);
             _sockfd = -1;
        }
    }   
    //创建一个服务端连接
    bool CreateServer(const uint16_t &port,const std::string &ip = "0.0.0.0",bool block_flag = false){
        //1.创建套接字 2.绑定地址 3.开始监听 4.设置非阻塞 5.启动地址重用
        if(Create() == false) return false;
        if(block_flag) NonBlock();
        if(Bind(ip,port) == false) return false;
        if(Listen() == false) return false;
        ReuseAddress();
        return true;
    }
    //创建一个客户端连接
    bool CreateClient(const uint16_t &port,const std::string &ip){
        //1.创建套接字  2.指向要连接的服务器
        if(Create() == false) return false;
        DBG_LOG("create client socket sucess");
        if(Connect(ip,port) == false) return false;
        return true;
    }
    //设置套接字选项----开启地址端口重用(进入timewiate状态)
    void ReuseAddress(){
        //int setsockopt(int sockfd, int level, int optname,const void optval[.optlen],socklen_t optlen);
        //int setsockopt(int sockfd,int level,int optname,void *val,it vallen)
        int val = 1;
        setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR,(void*)&val,sizeof(int));
        val = 1;
        setsockopt(_sockfd,SOL_SOCKET,SO_REUSEPORT,(void*)&val,sizeof(int));
    }
    //设置套接字阻塞属性-----设置为非阻塞
    void NonBlock(){
        //#include <fcntl.h>
        //int fcntl(int fd, int op, ... /* arg */ );
        int flag = fcntl(_sockfd,F_GETFL,0);
        fcntl(_sockfd,F_SETFL,flag | O_NONBLOCK);
    }
};



class Poller;
class EventLoop;
class Channel
{
    private:
        int _fd;
        EventLoop *_loop;
        uint32_t _events;   //当前需要监控的事件
        uint32_t _revents;  //当前连接触发的事件
        using EventCallback = std::function<void()>;
        EventCallback _read_callback;  //可读事件被触发时的回调函数
        EventCallback _write_callback; //可写事件被触发时的回调函数
        EventCallback _error_callback; //错误事件被触发时的回调函数 
        EventCallback _close_callback; //连接断开事件被触发时的回调函数
        EventCallback _event_callback; //任意事件被触发时的回调函数
    public:
        Channel(EventLoop *loop,int fd):_fd(fd),_events(0),_revents(0),_loop(loop){}
        int Fd(){ return _fd; }
        void SetREvents(uint32_t events) { _revents = events; }//设置实际就绪的事件
        uint32_t GetEvents() { return _events; }//获取想要监控的事件
        void SetReadCallback(const EventCallback &cb)  { _read_callback = cb; }
        void SetWriteCallback(const EventCallback &cb) { _write_callback = cb; }
        void SetErrorCallback(const EventCallback &cb) { _error_callback = cb; }
        void SetCloseCallback(const EventCallback &cb) { _close_callback = cb; }
        void SetEventCallback(const EventCallback &cb) { _event_callback = cb; }
        //当前是否监控了可读
        bool ReadAble() { return _events & EPOLLIN; }
        //当前是否监控了可写
        bool WriteAble() {return _events & EPOLLOUT; }
        //启动读事件监控,添加到epoll的红黑树中
        void EnableRead() { _events |= EPOLLIN; Update();} 
        //启动写事件监控,添加到epoll的红黑树中
        void EnableWrite() { _events |= EPOLLOUT; Update();}
        //关闭读事件监控
        void DisableRead() { _events &= ~EPOLLIN; Update();}
        //关闭写事件监控
        void DisableWrite() { _events &= ~EPOLLOUT; Update();}
        //关闭所有事件监控
        void DisableAll() { _events = 0; Update();}    
        //移除监控
        // void Remove() { return _poller->RemoveEvent(this); } 
        // void Update() { return _poller->UpdateEvent(this); }
        void Remove();
        void Update();
        //事件处理,一旦连接触发了事件,就调用这个函数,自己触发了什么事件如何处理自己决定
        void HandleEvent(){
            if((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI)){
                //不管任何事件触发,都要调用的函数
                if(_event_callback) _event_callback();//放到事件处理完毕以后调用,刷新活跃度
                if(_read_callback) _read_callback();
            }
            if(_revents & EPOLLOUT){
                //不管任何事件触发,都要调用的函数
                if(_event_callback) _event_callback();//放到事件处理完毕以后调用,刷新活跃度
                if(_write_callback) _write_callback();
            }
            else if(_revents & EPOLLERR){
                //不管任何事件触发,都要调用的函数
                if(_event_callback) _event_callback();
                if(_error_callback) _error_callback();//一旦出错,就会释放连接,因此要放到前边调用
            }
            else if(_revents & EPOLLHUP){
                //不管任何事件触发,都要调用的函数
                if(_event_callback) _event_callback();
                if(_close_callback) _close_callback();//一旦出错,就会释放连接,因此要放到前边调用
            }
        }
};




#define MAX_EPOLLEVENTS 1024
class Poller
{
    private:
        int _epfd;
        struct epoll_event _evs[MAX_EPOLLEVENTS];
        std::unordered_map<int,Channel*> _channels;
    private:
        //对epoll的直接操作
        void Update(Channel *channel,int op){
            //int epoll_ctl(int epfd, int op, int fd,struct epoll_event *_Nullable event);
            int fd = channel->Fd();
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = channel->GetEvents();
            int ret = epoll_ctl(_epfd,op,fd,&ev);
            if(ret < 0){
                ERR_LOG("Update():epoll_ctl failed!");
                abort();
            }
            return;
        }
        //判断一个Channel是否已经添加了事件监控
        bool HasChannel(Channel *channel){
            auto it = _channels.find(channel->Fd());
            if(it == _channels.end()){
                //说明不存在
                return false;
            }
            return true;
        }
    public:
        Poller(){
            _epfd = epoll_create(1);
            if(_epfd < 0){
                ERR_LOG("epoll_create failed!");
                abort();//退出
            }
        }
        //添加或修改监控事件
        void UpdateEvent(Channel *channel){
            bool ret = HasChannel(channel);
            if(ret == false){
                //不存在就添加
                _channels.insert(std::make_pair(channel->Fd(),channel));
                return Update(channel,EPOLL_CTL_ADD);
            }
            return Update(channel,EPOLL_CTL_MOD);
        }
        //移除监控
        void RemoveEvent(Channel *channel){
            auto it = _channels.find(channel->Fd());
            if(it != _channels.end()){
                _channels.erase(it);
            }
            Update(channel,EPOLL_CTL_DEL);
        }
        //开始监控,返回活跃连接
        void Poll(std::vector<Channel*> *active){
            // int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
            int nfds = epoll_wait(_epfd,_evs,MAX_EPOLLEVENTS,-1);//设置阻塞等待
            if(nfds < 0){
                if(errno == EINTR){
                    return;
                }
                ERR_LOG("epoll wait error:%s\n",strerror(errno));
                abort();
            }
            for(int i = 0; i < nfds;i++){
                auto it = _channels.find(_evs[i].data.fd);
                assert(it != _channels.end());
                it->second->SetREvents(_evs[i].events);//设置实际就绪的事件,设置到对应的Channel对象的_revents属性中
                active->push_back(it->second);
            }
            return;
        }
};

using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void ()>;
class TimerTask
{
    private:
        uint64_t _id;       //定时器任务对象ID,可以唯一性的定位找到定时器对象
        uint32_t _timeout;  //设置定时任务的超时时间
        bool _canceled;     //false--表示没有取消(执行),true--表示取消(不执行)
        TaskFunc _task_cb;  //定时器对象要执行的定时任务,组件自身不需要知道参数,组件使用者会使用 bind 函数绑定任务传进来,你只负责执行
        ReleaseFunc _release; //用于删除TimerWheel中保存的定时器对象信息
    public:
        TimerTask(uint64_t id,uint32_t timeout,const TaskFunc& cb)
        : _id(id), _timeout(timeout), _task_cb(cb),_canceled(false)
        {}
        ~TimerTask(){
             if(_canceled == false) 
                _task_cb(); 
             _release();
            }
        void SetRelease(const ReleaseFunc& cb) {_release = cb;}
        void Cancel() {_canceled = true;}
        uint32_t Get_TimeOut() {return _timeout;}
};

class TimerWheel
{
    private:
        using WeakTask = std::weak_ptr<TimerTask>;
        using PtrTask = std::shared_ptr<TimerTask>;//我们使用它的引用计数,
        int _tick;           //代表秒针,走到那个位置就释放那个位置,释放的位置我会存入 weak指针指向的shared_ptr指针指向的定时器对象
                             //在释放的时候会调用 TimerTask 的析构函数,就会自动调用 定时器任务对象 所对应的定时任务(由用户传入)
        int _capacity;       //代表表盘最大容量---其实就是最大延迟时间,你可以自己设置为30s or 60s等等
        std::vector<std::vector<PtrTask>> _wheel;
        std::unordered_map<uint64_t,WeakTask> _timers;  //把 TimerTask对象以weak_ptr的形式存起来,方便后边查找并制作shared_ptr
                                                        //管理所有的定时器任务对象
        EventLoop *_loop;
        int _timerfd;//定时器描述符---可读事件回调函数就是读取计数器,执行定时任务
        std::unique_ptr<Channel> _timer_channel;
    public:
        void RemoveTimer(const uint64_t id)
        {
            //先在 _timers中查找下有没有
            auto it = _timers.find(id);
            if(it != _timers.end())//找到啦
            {
                //将这个对象移除
                _timers.erase(id);
            }
        }
        static int CreateTimerfd(){
            int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
            if(timerfd < 0){
                ERR_LOG("create timerfd failed!!!");
                abort();
            }
            //int timer_settime(int timerfd, int flags,struct itimerspec *new,struct itimerspec *old);
            struct itimerspec itime;
            itime.it_value.tv_sec = 1;
            itime.it_value.tv_nsec = 0;//第一次超时时间为1s后
            itime.it_interval.tv_sec = 1;
            itime.it_interval.tv_nsec = 0;//第一次超时之后,每次超时时间间隔
            timerfd_settime(timerfd,0,&itime,NULL);
            return timerfd;
        }
        void ReadTimerfd(){
            uint64_t times;
            int ret = read(_timerfd,&times,sizeof(times));
            if(ret < 0){
                ERR_LOG("read timerfd failed!!!");
                abort();
            }
        }
        //秒针滴答向后走,走到哪里执行哪里的任务,这个函数每秒被执行一次,相当于秒针向后走了一步                              
        void RunTimerTask(){
            _tick = (_tick + 1) % _capacity;
            //清空指定位置的数组vector<PtrTask>,就会把数组中保存的所有管理定时器对象的shared_ptr释放掉
            //假如如果有一个shared_ptr计数器为1,释放掉为0,这时就要去释放定时器对象,执行析构->执行任务
            _wheel[_tick].clear();//执行到期任务
        }
        void OnTime(){
            ReadTimerfd();
            RunTimerTask();
        }
        //添加定时任务
        void TimerAddInLoop(uint64_t id,uint32_t timeout,const TaskFunc& cb){
            //先构建定时任务对象传递给shared_ptr
            PtrTask pt(new TimerTask(id,timeout,cb));
            pt->SetRelease(std::bind(&TimerWheel::RemoveTimer,this,id));
            //添加到 _timers哈希表 里
            _timers[id] = WeakTask(pt);
            //将 shared_ptr 放到 _wheel中
            uint32_t delay = pt->Get_TimeOut();
            int pos = (_tick + delay) % _capacity;//环形结构,越界后取模得到应该放入的位置
            _wheel[pos].push_back(pt);
        }
        //延迟定时任务
        void TimerRefreshInLoop(uint64_t id)
        {
            //思路:先通过保存的定时器对象的 weak_ptr 构造出来一个shared_ptr出来,然后添加到时间轮中
            auto it = _timers.find(id);
            if(it == _timers.end())
            {
                //说明没找到定时任务,没法刷新没法延迟,直接返回;
                return;
            }
            //找到了定时任务
            //1.先通过保存的定时器对象的 weak_ptr 构造出来一个shared_ptr出来
            PtrTask pt = it->second.lock();//lock函数获取 weak_ptr 管理的对象对应的shared_ptr
            //2.添加到时间轮中
            uint32_t delay = pt->Get_TimeOut();
            int pos = (_tick + delay) % _capacity;//环形结构,越界后取模得到应该放入的位置
            _wheel[pos].push_back(pt);
        }
        //取消定时任务
        void TimerCancelInLoop(const uint64_t id)
        {
            auto it = _timers.find(id);
            if(it == _timers.end())
            {
                //说明没找到定时任务,没法刷新没法延迟,直接返回;
                return;
            }
            PtrTask pt = it->second.lock();//lock函数获取 weak_ptr 管理的对象对应的shared_ptr
            if(pt) pt->Cancel();
        }
        //存在线程安全问题,只能在EventLoop对应的线程里边调用
        //这个接口实际上不能被外界使用者调用,只能在模块内,在对应的EventLoop线程内执行
        bool HasTimer(uint64_t id){
            //思路:先通过保存的定时器对象的 weak_ptr 构造出来一个shared_ptr出来,然后添加到时间轮中
            auto it = _timers.find(id);
            if(it == _timers.end())
            {
                //说明没找到定时任务,没法刷新没法延迟,直接返回;
                return false;
            }
            return true;
        }
    public:
        TimerWheel(EventLoop *loop)
        :_capacity(60),_tick(0),_wheel(_capacity),_loop(loop),_timerfd(CreateTimerfd()),_timer_channel(new Channel(_loop,_timerfd)){
            _timer_channel->SetReadCallback(std::bind(&TimerWheel::OnTime,this));
            _timer_channel->EnableRead();
        }
        void TimerAdd(uint64_t id,uint32_t timeout,const TaskFunc& cb);
        void TimerRefresh(uint64_t id);
        void TimerCancel(const uint64_t id);
};

class EventLoop
{
    private:
        using Functor = std::function<void()>;
        std::thread::id _thread_id;//EventLoop对应的线程的id
        Poller _poller;//进行所有文件描述符的事件监控
        int _event_fd;//唤醒IO事件监控有可能导致的阻塞使用eventfd()函数进行通知
        std::unique_ptr<Channel> _event_channel;
        //使用vector充当任务队列
        std::vector<Functor> _tasks;//任务池
        std::mutex _mutex;//实现任务池操作的线程安全
        TimerWheel _timer_wheel;
    public:
        //执行任务池中的所有任务
        void RunAllTask(){
            std::vector<Functor> functor;
            {
                std::unique_lock<std::mutex> _lock(_mutex);
                _tasks.swap(functor);
            }
            for(auto &f : functor){
                f();
            }
        }
        static int CreateEventFd(){
            int efd = eventfd(0,EFD_CLOEXEC | EFD_NONBLOCK);
            if(efd < 0){
                ERR_LOG("create eventfd failed!!!");
                abort();
            }
            return efd;
        }
        void ReadEventFd(){
            uint64_t res = 0;
            int ret = read(_event_fd,&res,sizeof(res));
            if(ret < 0){
                //EINTR----被信号打断   EAGAIN----表示没有数据可读
                if(errno == EINTR | errno==EAGAIN){
                    return; 
                }
                ERR_LOG("read eventfd failed!!!");
                abort();
            }
            return;
        }
        void WeakUpEventFd(){
            uint64_t val = 1;
            int ret = write(_event_fd,&val,sizeof(val));
            if(ret < 0){
                //EINTR----被信号打断   EAGAIN----表示没有数据可读
                if(errno == EINTR){
                    return; 
                }
                ERR_LOG("write eventfd failed!!!");
                abort();
            }
            return;
        }
    public:
        EventLoop():_thread_id(std::this_thread::get_id()),
                    _event_fd(CreateEventFd()),
                    _event_channel(new Channel(this,_event_fd)),
                    _timer_wheel(this){
                    //给eventfd添加可读事件回调函数,读取eventfd事件通知次数
                    _event_channel->SetReadCallback(std::bind(&EventLoop::ReadEventFd,this));
                    //启动eventfd的读事件监控
                    _event_channel->EnableRead();
                    }
        //事件监控->就绪事件处理->执行任务
        void Start(){
            //1.事件监控   2.事件处理    3.执行任务
            while(1){
                std::vector<Channel*> active;
                _poller.Poll(&active);
                for(auto &channel : active){
                    channel->HandleEvent();
                }
                RunAllTask();
            }
        }
        //用于判断当前线程是否是EventLoop对应的线程
        bool IsInLoop(){
            return (_thread_id == std::this_thread::get_id());
        }
        void AssertInLoop(){
            assert(_thread_id == std::this_thread::get_id());
        }
        //判断将要执行的任务是否处于当前线程中,如果是就执行,不是就压入队列
        void RunInLoop(const Functor &cb){
            if(IsInLoop()){
                return cb();
            }
            QueueInLoop(cb); 
        }
        //将操作压入任务池
        void QueueInLoop(const Functor &cb){
            {
                std::unique_lock<std::mutex> lock(_mutex);
                _tasks.push_back(cb);
            }
            //唤醒有可能因为没有事件就绪,而导致的epoll阻塞
            WeakUpEventFd();
        }
        //添加/修改描述符的事件监控
        void UpdateEvent(Channel *channel) { return _poller.UpdateEvent(channel); }
        //移除描述符的监控
        void RemoveEvent(Channel *channel) { return _poller.RemoveEvent(channel); }
        void TimerAdd(uint64_t id,uint32_t timeout,const TaskFunc& cb){
            return _timer_wheel.TimerAdd(id,timeout,cb);
        }
        void TimerRefresh(uint64_t id) { return _timer_wheel.TimerRefresh(id); }
        void TimerCancel(uint64_t id) { return _timer_wheel.TimerCancel(id); }
        bool HasTimer(uint64_t id) { return _timer_wheel.HasTimer(id); }


};

class LoopThread
{
    private:
        //互斥锁和条件变量,用于实现_loop获取的同步关系,避免线程创建了,但是_loop还没有实例化就获取_loop这个空窗期发生的错误
        std::mutex _mutex;  //互斥锁
        std::condition_variable _cond;//条件变量
        EventLoop *_loop;   //这个对象要在线程内部实例化
        std::thread _thread;//EventLoop对应的线程
    private:
        //实例化EventLoop对象,唤醒_cond上有可能阻塞的线程,并且运行EventLoop模块对应功能
        void ThreadEntry(){
            EventLoop loop;
            {
                std::unique_lock<std::mutex> lock(_mutex);
                _loop = &loop;
                _cond.notify_all();
            }
            _loop->Start();
        }
    public:
        //创建线程,设定线程入口函数
        LoopThread():_loop(NULL),_thread(std::thread(&LoopThread::ThreadEntry,this)){}
        //返回当前线程关联的EventLoop对象指针
        EventLoop *GetLoop(){
            EventLoop *loop = NULL;
            {
                std::unique_lock<std::mutex> lock(_mutex);//加锁
                _cond.wait(lock,[&](){ return _loop != NULL;});
                loop = _loop;
            }
            return loop;
        }

};
class LoopThreadPool
{
    private:
        int _thread_count;//从属线程数量
        int _next_loop_idx;
        EventLoop *_baseloop;//主EventLoop,运行在主线程,从属线程数量为0,则所有操作都在baseloop中进行
        std::vector<LoopThread*> _threads;//保存所有的LoopThread对象
        std::vector<EventLoop*> _loops;//从属线程数量大于0则从_loops中进行线程EventLoop分配
    public:
        LoopThreadPool(EventLoop *baseloop):_thread_count(0),_next_loop_idx(0),_baseloop(baseloop){}
        //设置线程数量
        void SetThreadCount(int count){
            _thread_count = count;
        }
        //创建所有从属线程
        void Create(){
            if(_thread_count > 0){
                _threads.resize(_thread_count);
                _loops.resize(_thread_count);
                for(int i = 0; i < _thread_count; i++){
                    _threads[i] = new LoopThread();
                    _loops[i] = _threads[i]->GetLoop();
                }
            }
            return ;
        }
        EventLoop *NextLoop(){
            if(_thread_count == 0){
                return _baseloop;
            }
            _next_loop_idx = (_next_loop_idx + 1) % _thread_count;
            return _loops[_next_loop_idx];
        }
};
class Any
{
    private:
        //父类只制定几个虚函数
        class holder {
            public:
                virtual ~holder() {}
                //纯虚函数:获取数据类型
                virtual const std::type_info& type() = 0;
                //通过一个 any对象构造一个any对象
                virtual holder* clone() = 0;
        };
        template<class T>
        class placeholder : public holder
        {
            public:
                placeholder(const T &val):_val(val){}//调用拷贝构造
                //纯虚函数:获取数据类型,获取子类对象保存的数据类型
                virtual const std::type_info& type() { return typeid(T); }
                //通过一个 any对象构造一个any对象,针对当前的对象自身,克隆出一个新的子类对象
                virtual holder* clone() { return new placeholder(_val); }
            public:
                T _val;//保存任意类型数据
        };
        holder* _content;
    public:
        Any() : _content(nullptr) {}
        template<class T>
        Any(const T& val) : _content(new placeholder<T>(val)) {}
        Any(const Any& other) : _content(other._content ? other._content->clone() : nullptr) {}
        ~Any(){ if(_content) delete _content;}

        Any& swap(Any &other){
            std::swap(_content,other._content);
            return *this;
        }

        template<class T>
        T *get(){
            //外界使用函数时,想要获取的数据类型必须和保存的数据类型一致
            assert(typeid(T) == _content->type());
            return &((placeholder<T>*)_content)->_val;
        }//返回子类对象保存数据的指针
        //赋值运算符的重载函数
        template<class T>
        Any& operator=(const T &val){
            //A = B 那就先用B中的值构造一个和B一样的临时对象C,然后让C与A交换,最后A中数据与C一致也就变相等于B赋值给A
            //并且我们也不用怕A中原本有数据会造成内存泄漏,因为临时对象C中带着原本A的指针,出了作用域C销毁进而调用析构就会清理掉
            //为val构造一个临时的通用容器,然后与当前容器自身进行指针交换,临时对象释放的时候,原本保存数据也就释放了
            Any(val).swap(*this);
            return *this;
        }
        Any& operator=(const Any &other){
            Any(other).swap(*this);
            return *this;
        }
};
class Connection;
//CONNECTING---连接刚建立成功待处理状态,这时候回调函数还没设置
//CONNECTED---连接建立完成,各种设置已经完成,可以通信的状态
//DISCONNECTING---待关闭状态
//DISCONNECTED---连接关闭状态,这时候无法对连接做任何处理,下一步就是真正释放这个连接
typedef enum { DISCONNECTED,CONNECTING,CONNECTED,DISCONNECTING}ConnStatu;
using PtrConnection = std::shared_ptr<Connection>;
class Connection : public std::enable_shared_from_this<Connection>
{
    private:
        uint64_t _conn_id; //连接的唯一ID,便于连接的管理和查找
        //uint64_t _timer_id; //定时器id,必须是唯一的,这块为了简化操作使用_conn_id作为定时器
        int _sockfd;       //连接关联的文件描述符
        bool _enable_inactive_release;//连接是否启动非活跃销毁的判断标志,默认为false
        EventLoop *_loop;//连接关联的一个EventLoop
        ConnStatu _statu;
        Socket _socket;    //套接字操作管理
        Channel _channel;  //连接的事件管理
        Buffer _in_buffer; //输入缓冲区---存放从socket中读取到的数据
        Buffer _out_buffer;//输出缓冲区---存放要发送给对端的数据
        Any _context;

        /*这四个回调函数，是让服务器模块来设置的（其实服务器模块的处理回调也是组件使用者设置的）*/
        /*换句话说，这几个回调都是组件使用者使用的*/
        using ConnectedCallback = std::function<void(const PtrConnection&)>;
        using MessageCallback = std::function<void(const PtrConnection&,Buffer*)>;
        using CloseCallback = std::function<void(const PtrConnection&)>;
        using AnyEventCallback = std::function<void(const PtrConnection&)>;
        ConnectedCallback _connected_callback;
        MessageCallback _message_callback;
        CloseCallback _closed_callback;
        AnyEventCallback _event_callback;
        /*组件内的连接关闭回调--组件内设置的，因为服务器组件内会把所有的连接管理起来，一旦某个连接要关闭*/
        /*就应该从管理的地方移除掉自己的信息*/
        CloseCallback _server_closed_callback;
    private:
        /*五个channel的事件回调函数*/
        //描述符可读事件触发后调用的函数,接收socket数据放到接收缓冲区中,然后调用_message_callback
        void HandleRead() {
            //1.接收socket的数据,放到缓冲区
            char buf[65536];
            ssize_t ret = _socket.NonBlockRecv(buf,65535);
            if(ret < 0){
                //出错了,不能直接真正关闭连接
                return ShutdownInLoop();
            }
            //ret == 0表示没有读取到数据,并不是连接断开,连接断开返回-1
            //2.将数据放到输入缓冲区,写入后将写偏移向后移动
            _in_buffer.WriteAndPush(buf,ret);
            //3.调用业务处理函数,在此之前需要确保输入缓冲区中有数据
            if(_in_buffer.ReadAbleSize() > 0){
                return _message_callback(shared_from_this(),&_in_buffer);
            }
        }
        //描述符可写事件触发后调用的函数
        void HandleWrite(){
            //把_out_buffer中的数据发送到socket发送缓冲区中
            ssize_t ret = _socket.NonBlockSend(_out_buffer.ReadPosition(),_out_buffer.ReadAbleSize());
            if(ret < 0){
                //发送错误就关闭连接,在关闭连接之前看看接收缓冲区中是否还有数据需要处理
                if(_in_buffer.ReadAbleSize() > 0){
                    _message_callback(shared_from_this(),&_in_buffer);
                }
                return ReleaseInLoop();//这时才是真正关闭连接
            }
            _out_buffer.MoveReadOffset(ret);//一定要将读偏移向后移动,不然就会一直发送重复数据
            //特殊情况处理
            if(_out_buffer.ReadAbleSize() == 0){//组件的发送换缓冲区已经没有数据了
                //解除写监控,不然就会造成_socket一直触发写监控但是组件内的发送缓冲区却是没有数据,loopbusy
                _channel.DisableWrite();
                //如果当前是链接关闭状态,有数据发送完数据关闭连接,没有数据就直接释放
                if(_statu == DISCONNECTING){
                    return ReleaseInLoop();
                }
            }
            return;
        }
        //描述符挂断事件触发后调用的函数
        void HandleClose(){
            //一旦连接挂断了,套接字就什么都干不了,因此有数据待处理就处理一下,完毕就关闭连接
            if(_in_buffer.ReadAbleSize() > 0){
                _message_callback(shared_from_this(),&_in_buffer);
            }
            return ReleaseInLoop();//这时才是真正关闭连接
        }
        //描述符错误事件触发后调用的函数
        void HandleError(){
            //一旦连接挂断了,套接字就什么都干不了,因此有数据待处理就处理一下,完毕就关闭连接
            if(_in_buffer.ReadAbleSize() > 0){
                _message_callback(shared_from_this(),&_in_buffer);
            }
            return ReleaseInLoop();//这时才是真正关闭连接
        }
        //描述符任意事件触发后调用的函数
        void HandleEvent(){
            //1.刷新连接的活跃度--延迟定时销毁任务
            if(_enable_inactive_release == true){
                _loop->TimerRefresh(_conn_id);
            }
            //2.调用组件使用者传入的任意事件回调
            if(_event_callback){
                _event_callback(shared_from_this());
            }
        }
        //连接获取之后,所处的状态下要进行各种设置(启动读监控,调用回调函数)
        void EstablishedInLoop(){
            //1.修改连接信息
            assert(_statu == CONNECTING);//当前的状态必须一定是上层组件定义的半连接状态,而不是通信套接字那种半链接
            _statu = CONNECTED;//当前函数执行完毕,标志连接进入完成状态,可以进行通信
            //2.启动读事件监控
            _channel.EnableRead();
            //3.调用用户设置的回调函数
            if(_connected_callback) _connected_callback(shared_from_this());
        }
        //这个接口才是实际的释放接口
        void ReleaseInLoop(){
            //1.修改连接状态,将其设置为DISCONNECTED
            _statu = DISCONNECTED;
            //2.移除连接的事件监控
            _channel.Remove();
            //3.关闭描述符
            _socket.Close();
            //4.如果当时定时器队列中还有定时销毁任务,则取消任务
            if(_loop->HasTimer(_conn_id)) CancelInactiveReleaseInLoop();
            //5.调用关闭回调函数,先调用组件使用者设置的函数,防止先移除服务器内部的连接管理信息造成的类似于野指针的问题
            if(_closed_callback) _closed_callback(shared_from_this());
            //6.移除服务器内部的管理信息
            if(_server_closed_callback) _server_closed_callback(shared_from_this());
        }
        //这个接口并不是真正的将组件发送缓冲区中数据发送到socket发送缓冲区中,而是将用户业务处理完的数据放到组件发送缓冲区,启动写事件监控
        void SendInLoop(Buffer buf){
            if(_statu == DISCONNECTED) return;
            // _out_buffer.WriteAndPush(data,len);
            _out_buffer.WriteBufferAndPush(buf);
            if(_channel.WriteAble() == false){
                _channel.EnableWrite();
            }
        }
        //这个关闭操作并不是实际的连接释放操作,需要判断还有没有数据待处理,待发送
        void ShutdownInLoop(){
            _statu = DISCONNECTING;//设置连接为半关闭状态
            if(_in_buffer.ReadAbleSize() > 0){
                if(_message_callback){
                    _message_callback(shared_from_this(),&_in_buffer);
                }
            }
            //要么就是写入数据的时候出错关闭,要么就是没有待发送数据,直接关闭
            if(_out_buffer.ReadAbleSize() > 0){
                if(_channel.WriteAble() == false){
                    _channel.EnableWrite();
                }
            }
            if(_out_buffer.ReadAbleSize() == 0){
                ReleaseInLoop();
            }
        }
        //启动非活跃连接超时释放规则
        void EnableInactiveReleaseInLoop(int sec){
            //1.更改标志位
            _enable_inactive_release = true;
            //2.如果当前定时销毁任务已经存在,那就刷新延迟一下即可
            if(_loop->HasTimer(_conn_id)){
                return _loop->TimerRefresh(_conn_id);
            }
            //3.如果不存在定时销毁任务,就新增
            _loop->TimerAdd(_conn_id,sec,std::bind(&Connection::ReleaseInLoop,this));
        }
        void CancelInactiveReleaseInLoop(){
            _enable_inactive_release = false;
            if(_loop->HasTimer(_conn_id)){
                _loop->TimerCancel(_conn_id);
            }
        }
        void UpgradeInLoop(const Any &context,const ConnectedCallback &conn,const MessageCallback &msg,
                     const CloseCallback &closed,const AnyEventCallback &event){
            _context = context;
            _connected_callback = conn;
            _message_callback = msg;
            _closed_callback = closed;
            _event_callback = event;
        }
    public:
        Connection(EventLoop *loop,uint64_t conn_id,int sockfd)
        :_conn_id(conn_id),
        _sockfd(sockfd),
        _enable_inactive_release(false),
        _loop(loop),
        _statu(CONNECTING),
        _socket(_sockfd),
        _channel(loop,_sockfd){
            _channel.SetCloseCallback(std::bind(&Connection::HandleClose,this));
            _channel.SetErrorCallback(std::bind(&Connection::HandleError,this));
            _channel.SetEventCallback(std::bind(&Connection::HandleEvent,this));
            _channel.SetReadCallback(std::bind(&Connection::HandleRead,this));
            _channel.SetWriteCallback(std::bind(&Connection::HandleWrite,this));
        }

        ~Connection(){
            DBG_LOG("release connection:%p",this);
        }
        //获取连接对应的文件描述符
        int Fd(){
            return _sockfd;
        }
        //获取连接id
        int Id(){
            return _conn_id;
        }
        //是否处于CONNECTED状态,是否处于通信状态
        bool Connected(){
            return (_statu == CONNECTED);
        }
        //设置上下文--连接建立完成时调用
        void SetContext(const Any &context){
            _context = context;
        }
        //获取上下文,返回的是指针,保证使用的是同一份上下文
        Any *GetContext(){
            return &_context;
        }
        //设置连接就绪完成之后的回调函数
        void SetConnectedCallback(const ConnectedCallback &cb){
            _connected_callback = cb;
        }
        //设置业务处理函数
        void SetMessageCallback(const MessageCallback &cb){
            _message_callback = cb;
        }
        //设置回调函数
        void SetCloseCallback(const CloseCallback &cb){
            _closed_callback = cb;
        }
        void SetAnyEventCallback(const AnyEventCallback &cb){
            _event_callback = cb;
        }
        void SetSrvCloseCallback(const CloseCallback &cb){ 
            _server_closed_callback = cb; 
        }
        //连接建立就绪后,进行channel回调设置,启动读监控,调用_connected_callback
        void Established(){
            _loop->RunInLoop(std::bind(&Connection::EstablishedInLoop,this));
        }
        //发送数据,将数据放到发送缓冲区,启动写事件,等到socket发送缓冲区有空间写了就放到socket发送缓冲区
        void Send(const char *data,size_t len){
            //外界传入的data，可能是个临时的空间，我们现在只是把发送操作压入了任务池，有可能并没有被立即执行
            //因此有可能执行的时候，data指向的空间有可能已经被释放了。
            Buffer buf;
            buf.WriteAndPush(data, len);
            _loop->RunInLoop(std::bind(&Connection::SendInLoop,this,buf));
        }
        //提供给组件使用者的关闭接口---并不是实际关闭接口,需要判断有没有数据待处理(发送缓冲区是否有数据未发送,接受缓冲区是否有数据待处理)
        void Shutdown(){
            _loop->RunInLoop(std::bind(&Connection::ShutdownInLoop,this));
        }
        //启动非活跃销毁,并定义多长时间无通信就是非活跃,添加定时任务
        void EnableInactiveRelease(int sec){
            _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop,this,sec));
        }
        //取消非活跃销毁
        void CancelInactiveRelease(){
            _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop,this));
        }
        //切换协议---重置上下文以及阶段性处理函数
        void Upgrade(const Any &context,const ConnectedCallback &conn,const MessageCallback &msg,
                     const CloseCallback &closed,const AnyEventCallback &event){
                        _loop->AssertInLoop();
                        _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop,this,context,conn,msg,closed,event));
                     }
};  
class Acceptor
{
    private:
        Socket _socket;//用于创建监听套接字
        EventLoop *_loop;//用于对监听套接字进行事件监控
        Channel _channel;//用于对监听套接字进行事件管理

        using AcceptCallback = std::function<void(int)>;
        AcceptCallback _accept_callback;
    private:
        //监听套接字的读事件回调处理函数---1.获取新连接  2.调用_accept_callback回调函数进行新连接处理
        void HandleRead(){
            int newfd = _socket.Accept();
            if(newfd < 0){
                return ;
            }
            if(_accept_callback){
                _accept_callback(newfd);
            }
        }
        int CreateServer(int port){
            bool ret = _socket.CreateServer(port);
            assert(ret == true);
            return _socket.Fd();
        }
    public:
        /*不能将启动读事件监控，放到构造函数中，必须在设置回调函数后，再去启动*/
        /*否则有可能造成启动监控后，立即有事件，处理的时候，回调函数还没设置：新连接得不到处理，且资源泄漏*/
        Acceptor(EventLoop *loop,int port):_socket(CreateServer(port)),_loop(loop),_channel(loop,_socket.Fd()){
            _channel.SetReadCallback(std::bind(&Acceptor::HandleRead,this));
            // _channel.EnableRead();
        }
        void SetAcceptCallback(const AcceptCallback &cb){
            _accept_callback = cb;
        }
        //启动读事件监控
        void Listen(){
            _channel.EnableRead();

        }
};
class TcpServer
{
    private:
        uint64_t _next_id;      //这是一个自动增长的连接ID，
        int _port;
        int _timeout;           //这是非活跃连接的统计时间---多长时间无通信就是非活跃连接
        bool _enable_inactive_release;//是否启动了非活跃连接超时销毁的判断标志
        EventLoop _baseloop;    //这是主线程的EventLoop对象，负责监听事件的处理
        Acceptor _acceptor;    //这是监听套接字的管理对象
        LoopThreadPool _pool;   //这是从属EventLoop线程池
        std::unordered_map<uint64_t, PtrConnection> _conns;//保存管理所有连接对应的shared_ptr对象

        using ConnectedCallback = std::function<void(const PtrConnection&)>;
        using MessageCallback = std::function<void(const PtrConnection&,Buffer*)>;
        using CloseCallback = std::function<void(const PtrConnection&)>;
        using AnyEventCallback = std::function<void(const PtrConnection&)>;
        using Functor = std::function<void()>;
        ConnectedCallback _connected_callback;
        MessageCallback _message_callback;
        CloseCallback _closed_callback;
        AnyEventCallback _event_callback;
    private:
        //为新连接构造一个Connection进行管理
        void NewConnection(int fd){
            _next_id++;
            PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
            conn->SetMessageCallback(_message_callback);
            conn->SetCloseCallback(_closed_callback);
            conn->SetConnectedCallback(_connected_callback);
            conn->SetAnyEventCallback(_event_callback);
            conn->SetSrvCloseCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
            if (_enable_inactive_release) conn->EnableInactiveRelease(_timeout);//启动非活跃超时销毁
            conn->Established();//就绪初始化
            _conns.insert(std::make_pair(_next_id, conn));
        }
        void RemoveConnectionInLoop(const PtrConnection &conn){
            int id = conn->Id();
            auto it = _conns.find(id);
            if (it != _conns.end()) {
                _conns.erase(it);
            }
        }
        //从管理Connection的_conns中移除连接信息
        void RemoveConnection(const PtrConnection &conn){
            _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
        }
        void RunAfterInLoop(const Functor &task,int delay){
            _next_id++;
            _baseloop.TimerAdd(_next_id,delay,task);
        }
    public:
        TcpServer(int port):_next_id(0),_port(port),_timeout(0),_enable_inactive_release(false),
                            _acceptor(&_baseloop,port),_pool(&_baseloop){
            _pool.Create();//创建线程池中的从属线程
            _acceptor.Listen();//将监听套接挂到baseloop上,将监听套接字设置到红黑树上,但是还没有开始监听
        }
        void SetThreadCount(int count);
        void SetConnectedCallback(const ConnectedCallback &cb){
            _connected_callback = cb;
        }
        //设置业务处理函数
        void SetMessageCallback(const MessageCallback &cb){
            _message_callback = cb;
        }
        //设置回调函数
        void SetCloseCallback(const CloseCallback &cb){
            _closed_callback = cb;
        }
        void SetAnyEventCallback(const AnyEventCallback &cb){
            _event_callback = cb;
        }
        void EnableInactiveRelease(int timeout){
            _timeout = timeout;
            _enable_inactive_release = true;
        }
        //用于添加一个定时任务
        void RunAfter(const Functor &task,int delay){
            _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop,this,task,delay));
        }
        void Start(){
            return _baseloop.Start();
        }


};

void Channel::Remove() { return _loop->RemoveEvent(this); } 
void Channel::Update() { return _loop->UpdateEvent(this); }
void TimerWheel::TimerAdd(uint64_t id,uint32_t timeout,const TaskFunc& cb){
    _loop->RunInLoop(std::bind(&TimerWheel::TimerAddInLoop,this,id,timeout,cb));
}
void TimerWheel::TimerRefresh(uint64_t id){
    _loop->RunInLoop(std::bind(&TimerWheel::TimerRefreshInLoop,this,id));
}
void TimerWheel::TimerCancel(const uint64_t id){
    _loop->RunInLoop(std::bind(&TimerWheel::TimerCancelInLoop,this,id));
}








